package com.mz.ieann.doplayer.audio.core.impl.media

import android.content.Context
import android.content.res.AssetFileDescriptor
import android.media.MediaPlayer
import android.os.Build
import android.util.Log
import android.view.ViewGroup
import com.mz.ieann.doplayer.audio.core.listener.IAudioPlayer
import com.mz.ieann.doplayer.audio.listener.PlayStatusListener
import com.mz.ieann.doplayer.audio.listener.ProgressListener
import com.mz.ieann.doplayer.audio.widget.YouVisualizerView

/**
 * <p>------------------------------------------------------
 * <p>Copyright (C) 2020 wasu company, All rights reserved.
 * <p>------------------------------------------------------
 * <p>
 * <p>
 *
 * @author Created by zhangmz
 * @date on 2023/5/11
 */
class MediaPlayerWrapper(
    private val TAG: String,
    private val context: Context
): PlayStatusListener(), IAudioPlayer {

    private var player: MediaPlayer? = null
    private var visualizerView: YouVisualizerView? = null
    private var progressListener: ProgressListener? = null

    private var effectsUtil: MediaEffectsUtil? = null

    override fun create(assetFile: AssetFileDescriptor): IAudioPlayer {
        if (isPlaying()){
            pause()
            return this
        }
        stop()
        if (player == null){
            player = MediaPlayer()
        }else {
            player?.reset()
        }
        addListener()
        player?.setDataSource(assetFile.fileDescriptor, assetFile.startOffset, assetFile.length)
        return this
    }

    override fun addListener(listener: ProgressListener?): IAudioPlayer {
        progressListener = listener
        return this
    }

    override fun addVisualizer(visualizerView: YouVisualizerView?): IAudioPlayer {
        this.visualizerView = visualizerView
        return this
    }

    override fun prepare(view: ViewGroup){
        player?.isLooping = true
        player?.prepare()
        effectsUtil = MediaEffectsUtil(TAG, player!!, visualizerView)
            .setupVisualizer(progressListener)
            .setupEqualizer(context, view)
            .setupBassBoost(context, view)
            .setupPresetReverb(context, view)
    }

    override fun updateProgress(progress: Int) {
        Log.v(TAG, "updateProgress, progress:$progress")
        if (progress == 0){
            return
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            player?.seekTo(progress.toLong(), MediaPlayer.SEEK_CLOSEST)
        }else {
            player?.seekTo(progress)
        }
    }

    override fun onPrepared(mp: MediaPlayer?) {
        super.onPrepared(mp)
        mp?.start()
        progressListener?.updateProgress(mp?.duration?: 0, mp?.currentPosition?: 0)
        Log.v(TAG, "onPrepared, duration:${mp?.duration}; currentPosition:${mp?.currentPosition}")
    }

    override fun onInfo(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
        Log.v(TAG, "onInfo, what:$what; extra:$extra")
        return super.onInfo(mp, what, extra)
    }

    override fun onError(mp: MediaPlayer?, what: Int, extra: Int): Boolean {
        Log.v(TAG, "onError, what:$what; extra:$extra")
        return super.onError(mp, what, extra)
    }

    override fun onCompletion(mp: MediaPlayer?) {
        Log.v(TAG, "onCompletion")
        super.onCompletion(mp)
        effectsUtil?.release()
    }

    override fun onSeekComplete(mp: MediaPlayer?) {
        super.onSeekComplete(mp)
        Log.v(TAG, "onSeekComplete")
    }

    private fun addListener(){
        player?.setOnPreparedListener(this)
        player?.setOnCompletionListener(this)
        player?.setOnErrorListener(this)
        player?.setOnInfoListener(this)
        player?.setOnBufferingUpdateListener(this)
        player?.setOnSeekCompleteListener(this)
    }

    override fun isPlaying(): Boolean {
        Log.v(TAG, "mediaPlayer isPlaying:${player?.isPlaying}; player:$player")
        return player?.isPlaying?: false
    }

    override fun seek(offset: Int) {
        Log.v(TAG, "mediaPlayer seek, offset:$offset")
        player?.seekTo(offset)
    }

    override fun resume() {
        player?.start()
    }

    override fun pause() {
        Log.v(TAG, "mediaPlayer pause")
        player?.pause()
    }

    override fun stop() {
        if (isPlaying()){
            Log.v(TAG, "mediaPlayer stop")
            player?.stop()
        }
    }

    override fun release() {
        if (isPlaying()){
            player?.stop()
        }
        Log.v(TAG, "mediaPlayer release")
        effectsUtil?.release()
        player?.release()
        visualizerView = null
    }

}